<?php

class Session_Mongo
{

	protected $_config = array('lifetime' => 86400, );

	protected $_session = array();

	/**
	 * Open does absolutely nothing as we already have an open connection.
	 *
	 * @access  public
	 * @return  bool
	 */
	public function open($save_path, $session_name)
	{
		return true;
	}

	/**
	 * Close does absolutely nothing as we can assume __destruct handles
	 * things just fine.
	 *
	 * @access  public
	 * @return  bool
	 */
	public function close()
	{
		return true;
	}

	/**
	 * Read the session data.
	 *
	 * @access  public
	 * @param string  $id
	 * @return  string
	 */
	public function read($id)
	{
		// retrieve valid session data
		$expiry = time() + (int)$this -> _config['lifetime'];

		// exclude results that are inactive or expired
		$result = DbNosql::inst() -> findOne('session', array('_id' => $id));

		if ($result)
		{
			$this -> _session = $result;
			return $result['data'];
		}

		return '';
	}

	/**
	 * Atomically write data to the session.
	 *
	 * @access  public
	 * @param   string  $id
	 * @param   mixed   $data
	 * @return  bool
	 */
	public function write($id, $data)
	{
		// create expires
		$expiry = time() + $this -> _config['lifetime'];

		// create new session data
		$new_obj = array(
			'_id' => $id,
			'data' => $data,
			'active' => 1,
			'expiry' => $expiry
		);

		// check for existing session for merge
		if (!empty($this -> _session))
		{
			$new_obj = array_merge($this -> _session, $new_obj);
		}

		// perform the update or insert
		try
		{
			DbNosql::inst() -> save('session', $new_obj);
		}
		catch (Exception $e)
		{
			echo $e -> getMessage();
			return FALSE;
		}

		return TRUE;
	}

	/**
	 * Destroys the session by removing the document with
	 * matching session_id.
	 *
	 * @access  public
	 * @param   string  $id
	 * @return  bool
	 */
	public function destroy($id)
	{
		Mongo::inst() -> remove(array('_id' => $id), array('safe' => true));
		return TRUE;
	}

	/**
	 * Garbage collection. Remove all expired entries atomically.
	 *
	 * @access  public
	 * @return  bool
	 */
	public function gc()
	{
		// define the query
		$query = array('expiry' => array(':lt' => time()));

		// specify the update vars
		$update = array('$set' => array('active' => 0));

		// update expired elements and set to inactive
		DbNosql::inst() -> remove('session', $query);

		return TRUE;
	}

}
